package com.maimao.goods.service;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.maimao.core.exception.MaiMaoDaoException;
import com.maimao.goods.mapper.GoodsDetailMapper;
import com.maimao.goods.mapper.GoodsMapper;
import com.maimao.goods.mapper.GoodsSkuMapper;
import com.maimao.model.goods.GoodsDetail;
import com.maimao.model.goods.GoodsSku;
import com.maimao.model.goods.SpecDetails;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.NotBlank;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author MaoLin Wang
 * @date 2021/1/25 10:54 上午
 */
@Service
public class SkuService {
    @Autowired
    private GoodsSkuMapper goodsSkuMapper;

    @Autowired
    private GoodsService goodsService;

    @Autowired
    private SpecDetailService specDetailService;


    /**
     * 检查sku库存是否足够当前需求量
     *
     * @param data
     * @return
     */
    public boolean checkSkuBatch(Map<Long, Integer> data) {
        Set<Long> skuIds = data.keySet();
        List<GoodsSku> goodsSkuList = goodsSkuMapper.selectByIdsBatchValid(Lists.newArrayList(skuIds));
        if (goodsSkuList == null || goodsSkuList.size() <= 0 || goodsSkuList.size() != skuIds.size()) {
            return false;
        }
        Map<Long, List<GoodsSku>> skuMap = goodsSkuList.stream().collect(Collectors.groupingBy(GoodsSku::getId));
        for (Map.Entry<Long, Integer> entry : data.entrySet()) {
            Long skuId = entry.getKey();
            Integer num = entry.getValue();
            List<GoodsSku> goodsSkus = skuMap.get(skuId);
            if (goodsSkus == null || goodsSkus.size() != 1) {
                return false;
            }
            if (goodsSkus.get(0).getStock() <= 0 || goodsSkus.get(0).getStock() < num) {
                return false;
            }
        }
        return true;
    }

    /**
     * 先过滤掉sku库存不足和valid为0的，再过滤掉goods的status不为1的和未上架的
     * @param skuIds
     * @return
     */
    public List<Long> checkSkuBatchWithRes(List<Long> skuIds) {
        List<GoodsSku> goodsSkuList = goodsSkuMapper.selectByIdsBatchValid(Lists.newArrayList(skuIds));
        List<Long> invalidIds = Lists.newArrayListWithCapacity(skuIds.size());

        if (ObjectUtil.isEmpty(goodsSkuList)) {
            invalidIds.addAll(skuIds);
            return invalidIds;
        }
        List<Long> goodsSkuIds = goodsSkuList.stream().map(GoodsSku::getId).collect(Collectors.toList());
        if (goodsSkuIds.size() != skuIds.size()) {
            //移除有效的skuId
            skuIds.removeAll(goodsSkuList);
            //剩下的都是无效的
            invalidIds.addAll(skuIds);
        }
        //待校验的商品ID
        Set<Long> goodsIds = goodsSkuList.stream().map(GoodsSku::getGoodsId).collect(Collectors.toSet());
        List<Long> invalidGoodsIds = goodsService.checkSpuBatchWithInvalid(Lists.newArrayList(goodsIds));
        if (ObjectUtil.isNotEmpty(invalidGoodsIds)) {
            List<Long> invalidskuIds = goodsSkuList.stream()
                    //过滤掉无效的商品
                    .filter(sku -> invalidGoodsIds.contains(sku.getGoodsId()))
                    .map(GoodsSku::getId).collect(Collectors.toList());
            if (ObjectUtil.isNotEmpty(invalidskuIds)){
                invalidIds.addAll(invalidskuIds);
            }
        }
        return invalidIds;


    }

    @Transactional(rollbackFor = MaiMaoDaoException.class)
    public void updateBatch(List<GoodsSku> skus) {
        goodsSkuMapper.updateBatch(skus);
    }

    /**
     * 批量查询sku秒杀信息
     */
    public List<GoodsSku> selectKillInfoBatch(List<Long> skuIds) {
        List<GoodsSku> skus = goodsSkuMapper.selectKillInfoByIdsBatchValid(skuIds);
        if (ObjectUtil.isNotEmpty(skus)) {
            for (GoodsSku goodsSku : skus) {
                String spec = goodsSku.getSpec();
                try {
                    Map<String, Object> specMap = JSON.parseObject(spec, Map.class);
                    StringBuilder sb = new StringBuilder();
                    for (Map.Entry<String, Object> entry : specMap.entrySet()) {
                        Integer specDetailId = Integer.valueOf(entry.getKey());
                        Object specVal = entry.getValue();
                        SpecDetails specDetails = specDetailService.selectByIdCache(specDetailId);
                        if (specDetails != null) {
                            sb.append(specDetails.getName() + ":" + specVal + (Optional.ofNullable(specDetails.getUnit()).orElse("")) + "\n");
                        }

                    }
                    goodsSku.setSpecStr(sb.toString());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return skus;
    }


}
